/**
 * 伤害效果处理器
 * 处理所有伤害类型的技能效果
 */

import { 
    ISkillEffectHandler, 
    SkillEffectType, 
    SkillEffectContext, 
    SkillEffectConfig, 
    SkillEffectResult,
    BattleEffect 
} from '../SkillEffectTypes';
import { ServiceLogger } from '../../../../../infrastructure/logging/UnifiedLogger';

/**
 * 伤害计算结果
 */
interface DamageCalculation {
    baseDamage: number;
    finalDamage: number;
    isCritical: boolean;
    isBlocked: boolean;
    damageType: 'physical' | 'magical' | 'true';
    modifiers: Array<{
        source: string;
        type: string;
        value: number;
    }>;
}

/**
 * 伤害效果处理器
 */
export default class DamageEffectHandler implements ISkillEffectHandler {
    readonly effectType = SkillEffectType.DAMAGE;
    readonly priority = 100;
    
    private logger: ServiceLogger;

    constructor() {
        this.logger = new ServiceLogger('DamageEffectHandler');
    }

    /**
     * 检查是否可以处理该效果
     */
    canHandle(context: SkillEffectContext): boolean {
        return context.targets.length > 0 && 
               context.targets.some(target => !target.component?.isDie());
    }

    /**
     * 执行伤害效果
     */
    async execute(context: SkillEffectContext, config: SkillEffectConfig): Promise<SkillEffectResult> {
        const battleEffects: BattleEffect[] = [];
        const affectedTargets: string[] = [];
        let totalDamage = 0;

        try {
            // 过滤存活目标
            const validTargets = context.targets.filter(target => 
                !target.component?.isDie() && 
                this.isValidTarget(target, config.targetType)
            );

            if (validTargets.length === 0) {
                return {
                    success: false,
                    battleEffects: [],
                    affectedTargets: [],
                    description: 'No valid targets for damage'
                };
            }

            // 对每个目标造成伤害
            for (const target of validTargets) {
                const damageCalc = await this.calculateDamage(context, config, target);
                
                if (damageCalc.finalDamage > 0) {
                    // 应用伤害
                    await this.applyDamage(target, damageCalc);
                    
                    // 创建战斗效果
                    const battleEffect: BattleEffect = {
                        effectId: this.generateEffectId(),
                        type: 'damage',
                        sourceId: context.caster.id,
                        targetId: target.id,
                        value: damageCalc.finalDamage,
                        description: this.generateDamageDescription(damageCalc),
                        isCritical: damageCalc.isCritical,
                        isBlocked: damageCalc.isBlocked,
                        metadata: {
                            damageType: damageCalc.damageType,
                            baseDamage: damageCalc.baseDamage,
                            modifiers: damageCalc.modifiers
                        }
                    };

                    battleEffects.push(battleEffect);
                    affectedTargets.push(target.id);
                    totalDamage += damageCalc.finalDamage;

                    this.logger.debug(`Damage applied`, {
                        metadata: {
                            sourceId: context.caster.id,
                            targetId: target.id,
                            damage: damageCalc.finalDamage,
                            isCritical: damageCalc.isCritical,
                            damageType: damageCalc.damageType
                        }
                    });
                }
            }

            return {
                success: true,
                battleEffects,
                affectedTargets,
                description: `造成了 ${totalDamage} 点伤害`,
                metadata: {
                    totalDamage,
                    targetCount: affectedTargets.length,
                    effectType: config.type
                }
            };

        } catch (error) {
            this.logger.error('Damage effect execution failed', undefined, error);
            return {
                success: false,
                battleEffects: [],
                affectedTargets: [],
                description: `伤害效果执行失败: ${(error as Error).message}`
            };
        }
    }

    /**
     * 验证配置
     */
    validateConfig(config: SkillEffectConfig): boolean {
        // 检查必需字段
        if (typeof config.power !== 'number' || config.power < 0) {
            return false;
        }

        // 检查目标类型
        const validTargetTypes = ['self', 'ally', 'enemy', 'all'];
        if (!validTargetTypes.includes(config.targetType)) {
            return false;
        }

        // 检查伤害类型参数
        if (config.params?.damageType) {
            const validDamageTypes = ['physical', 'magical', 'true'];
            if (!validDamageTypes.includes(config.params.damageType)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 获取效果描述
     */
    getDescription(config: SkillEffectConfig, context?: SkillEffectContext): string {
        const damageType = config.params?.damageType || 'physical';
        const damageTypeText: Record<string, string> = {
            physical: '物理',
            magical: '魔法',
            true: '真实'
        };
        const typeText = damageTypeText[damageType] || '未知';

        let description = `造成 ${config.power} 点${typeText}伤害`;
        
        if (config.probability && config.probability < 1) {
            description += ` (${(config.probability * 100).toFixed(0)}% 概率)`;
        }

        if (context && context.skillData) {
            const level = context.skillData.level || 1;
            const levelBonus = Math.floor(config.power * (level - 1) * 0.1);
            if (levelBonus > 0) {
                description += ` (+${levelBonus} 等级加成)`;
            }
        }

        return description;
    }

    // ==================== 私有方法 ====================

    /**
     * 计算伤害
     */
    private async calculateDamage(
        context: SkillEffectContext, 
        config: SkillEffectConfig, 
        target: any
    ): Promise<DamageCalculation> {
        const damageType = config.params?.damageType || 'physical';
        const modifiers: Array<{ source: string; type: string; value: number }> = [];

        // 基础伤害
        let baseDamage = config.power;
        
        // 技能等级加成
        const level = context.skillData?.level || 1;
        const levelMultiplier = 1 + (level - 1) * 0.1;
        baseDamage *= levelMultiplier;
        modifiers.push({
            source: 'skill_level',
            type: 'multiplicative',
            value: levelMultiplier
        });

        // 永久提升加成
        const permanentBoost = context.skillData?.damage || 0;
        baseDamage += permanentBoost;
        if (permanentBoost > 0) {
            modifiers.push({
                source: 'permanent_boost',
                type: 'additive',
                value: permanentBoost
            });
        }

        // 攻击力加成
        const caster = context.caster;
        let attackPower = 0;
        
        if (damageType === 'physical') {
            attackPower = caster.component?.getAttribute('攻击力') || 0;
        } else if (damageType === 'magical') {
            attackPower = caster.component?.getAttribute('法术强度') || 
                         caster.component?.getAttribute('攻击力') || 0;
        }

        const attackBonus = attackPower * (config.params?.attackPowerRatio || 0.5);
        baseDamage += attackBonus;
        if (attackBonus > 0) {
            modifiers.push({
                source: 'attack_power',
                type: 'additive',
                value: attackBonus
            });
        }

        // 暴击计算
        const criticalChance = caster.component?.getAttribute('暴击率') || 0.05;
        const isCritical = Math.random() < criticalChance;
        let finalDamage = baseDamage;

        if (isCritical) {
            const criticalMultiplier = caster.component?.getAttribute('暴击伤害') || 1.5;
            finalDamage *= criticalMultiplier;
            modifiers.push({
                source: 'critical_hit',
                type: 'multiplicative',
                value: criticalMultiplier
            });
        }

        // 防御减免（真实伤害不受防御影响）
        let isBlocked = false;
        if (damageType !== 'true') {
            let defense = 0;
            if (damageType === 'physical') {
                defense = target.component?.getAttribute('防御力') || 0;
            } else if (damageType === 'magical') {
                defense = target.component?.getAttribute('法术防御') || 
                         target.component?.getAttribute('防御力') || 0;
            }

            // 防御减伤公式
            const damageReduction = defense / (defense + 100);
            finalDamage *= (1 - damageReduction);
            
            if (damageReduction > 0) {
                modifiers.push({
                    source: 'defense',
                    type: 'multiplicative',
                    value: 1 - damageReduction
                });
            }
        }

        // 格挡检查
        const blockChance = target.component?.getAttribute('格挡率') || 0;
        isBlocked = Math.random() < blockChance;
        if (isBlocked) {
            finalDamage *= 0.5; // 格挡减少50%伤害
            modifiers.push({
                source: 'block',
                type: 'multiplicative',
                value: 0.5
            });
        }

        // 随机浮动
        const variance = config.params?.damageVariance || 0.1;
        const randomFactor = 1 + (Math.random() - 0.5) * 2 * variance;
        finalDamage *= randomFactor;

        return {
            baseDamage,
            finalDamage: Math.max(1, Math.floor(finalDamage)), // 至少造成1点伤害
            isCritical,
            isBlocked,
            damageType: damageType as any,
            modifiers
        };
    }

    /**
     * 应用伤害
     */
    private async applyDamage(target: any, damageCalc: DamageCalculation): Promise<void> {
        const component = target.component;
        if (!component) return;

        // 扣除生命值
        const oldHp = component.hp_now;
        component.hp_now = Math.max(0, component.hp_now - damageCalc.finalDamage);
        
        // 记录伤害
        this.logger.info('Damage applied to target', {
            metadata: {
                targetId: target.id,
                damage: damageCalc.finalDamage,
                oldHp,
                newHp: component.hp_now,
                damageType: damageCalc.damageType,
                isCritical: damageCalc.isCritical,
                isBlocked: damageCalc.isBlocked
            }
        });
    }

    /**
     * 检查目标是否有效
     */
    private isValidTarget(target: any, targetType: string): boolean {
        switch (targetType) {
            case 'enemy':
                return target.type !== 'ally'; // 简化实现
            case 'ally':
                return target.type === 'ally';
            case 'self':
                return target.id === target.id; // 这里需要更准确的判断
            case 'all':
                return true;
            default:
                return false;
        }
    }

    /**
     * 生成伤害描述
     */
    private generateDamageDescription(damageCalc: DamageCalculation): string {
        let description = `造成 ${damageCalc.finalDamage} 点`;
        
        const damageTypeText: Record<string, string> = {
            physical: '物理',
            magical: '魔法',
            true: '真实'
        };
        const typeText = damageTypeText[damageCalc.damageType] || '未知';
        
        description += typeText + '伤害';
        
        if (damageCalc.isCritical) {
            description += ' (暴击!)';
        }
        
        if (damageCalc.isBlocked) {
            description += ' (被格挡)';
        }
        
        return description;
    }

    /**
     * 生成效果ID
     */
    private generateEffectId(): string {
        return `damage_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    }
}
